from flask import Blueprint, request, jsonify
from models import db, Users, Tasks, Rewards, TaskRecords, RewardRecords, UserPoints
from werkzeug.security import generate_password_hash, check_password_hash

bp = Blueprint('api', __name__, url_prefix='/api')


@bp.route('/register', methods=['POST'])
def register():
    data = request.json
    username = data['username']
    password = data['password']

    if Users.query.filter_by(username=username).first():
        return jsonify({"error": "User already exists"}), 400

    password_hash = generate_password_hash(password)
    new_user = Users(username=username, password_hash=password_hash)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"message": "User registered successfully"}), 201


@bp.route('/login', methods=['POST'])
def login():
    data = request.json
    username = data['username']
    password = data['password']

    user = Users.query.filter_by(username=username).first()

    if user and check_password_hash(user.password_hash, password):
        user_points = UserPoints.query.filter_by(user_id=user.id).first()
        points = user_points.points if user_points else 0
        return jsonify({"message": "Login successful", "user_id": user.id, "points": points}), 200
    else:
        return jsonify({"error": "Invalid credentials"}), 401


@bp.route('/tasks', methods=['POST'])
def add_task():
    data = request.json
    user_id = data['user_id']
    task_name = data['task_name']
    description = data.get('description')
    points = data['points']

    new_task = Tasks(user_id=user_id, task_name=task_name,
                     description=description, points=points)
    db.session.add(new_task)
    db.session.commit()

    return jsonify({"message": "Task added successfully"}), 201


@bp.route('/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    data = request.json
    task = Tasks.query.get(task_id)

    if not task:
        return jsonify({"error": "Task not found"}), 404

    task.task_name = data.get('task_name', task.task_name)
    task.description = data.get('description', task.description)
    task.points = data.get('points', task.points)

    db.session.commit()

    return jsonify({"message": "Task updated successfully"}), 200


@bp.route('/tasks/<int:task_id>/complete', methods=['POST'])
def complete_task(task_id):
    data = request.json
    user_id = data['user_id']
    task = Tasks.query.get(task_id)

    if not task:
        return jsonify({"error": "Task not found"}), 404

    points_earned = task.points
    new_record = TaskRecords(
        user_id=user_id, task_id=task_id, points_earned=points_earned)
    db.session.add(new_record)
    db.session.commit()

    return jsonify({"message": "Task completed successfully"}), 201


@bp.route('/tasks', methods=['GET'])
def get_tasks():
    user_id = request.args.get('user_id')

    if not user_id:
        return jsonify({"error": "User ID is required"}), 400

    tasks = Tasks.query.filter_by(user_id=user_id).all()

    tasks_list = [{
        "id": task.id,
        "task_name": task.task_name,
        "description": task.description,
        "points": task.points,
        "created_at": task.created_at
    } for task in tasks]

    return jsonify(tasks_list), 200


@bp.route('/rewards', methods=['POST'])
def add_reward():
    data = request.json
    user_id = data['user_id']
    reward_name = data['reward_name']
    description = data.get('description')
    points_cost = data['points_cost']

    new_reward = Rewards(user_id=user_id, reward_name=reward_name,
                         description=description, points_cost=points_cost)
    db.session.add(new_reward)
    db.session.commit()

    return jsonify({"message": "Reward added successfully"}), 201


@bp.route('/rewards/<int:reward_id>', methods=['PUT'])
def update_reward(reward_id):
    data = request.json
    reward = Rewards.query.get(reward_id)

    if not reward:
        return jsonify({"error": "Rewards not found"}), 404

    reward.reward_name = data.get('reward_name', reward.reward_name)
    reward.description = data.get('description', reward.description)
    reward.points_cost = data.get('points_cost', reward.points_cost)

    db.session.commit()

    return jsonify({"message": "Reward updated successfully"}), 200


@bp.route('/rewards/<int:reward_id>/redeem', methods=['POST'])
def redeem_reward(reward_id):
    data = request.json
    user_id = data['user_id']
    reward = Rewards.query.get(reward_id)

    if not reward:
        return jsonify({"error": "Reward not found"}), 404

    points_spent = reward.points_cost
    new_record = RewardRecords(
        user_id=user_id, reward_id=reward_id, points_spent=points_spent)
    db.session.add(new_record)
    db.session.commit()

    return jsonify({"message": "Reward redeemed successfully"}), 201


@bp.route('/rewards', methods=['GET'])
def get_rewards():
    user_id = request.args.get('user_id')

    if not user_id:
        return jsonify({"error": "User ID is required"}), 400

    rewards = Rewards.query.filter_by(user_id=user_id).all()

    rewards_list = [{
        "id": reward.id,
        "reward_name": reward.reward_name,
        "description": reward.description,
        "points_cost": reward.points_cost,
        "created_at": reward.created_at
    } for reward in rewards]

    return jsonify(rewards_list), 200


@bp.route('/user_points', methods=['GET'])
def get_user_points():
    user_id = request.args.get('user_id')

    if not user_id:
        return jsonify({"error": "User ID is required"}), 400

    points = UserPoints.query.filter_by(user_id=user_id).first()
    if points:
        return jsonify({'point': points.points}), 200
